导航菜单
首页 >  Upload files with NextJS + Fetch + Api routes + Typescript  > File upload in Next.js App Router (13.4)

File upload in Next.js App Router (13.4)

File upload in Next.js App Router (13.4)Lucas Hang

Lucas Hang

·

Follow

2 min read·May 5, 2023

--

A short and practical article showing one way you can upload and storage files in Next.js ^13.4.0 using only Next itself

Next.js and Supabase Logos side-by-side in a green gradient backgroundGot image from this supabase articleWhat we are building

First of all, we are using Next.js version 13.4.0 with appDir enabled (it was just released as stable).Let’s see if this solution fits your need. In this example we’ll have a Next.js frontend page that takes files with and sends it in a FormData through fetch() to a Next.js API route. This route then will organize the received files and storage it using Supabase Storage.

The API route first

Your are probably more interested in this part. So, today I discovered that NextRequest class has a async function called formData(), that gives to you the formData received through the request. After that things got very simple, that might explain why I couldn’t find any content about it, but you — as me — may need that little help. Take a look:

// app/api/upload/route.ts

import { NextRequest, NextResponse } from 'next/server';

import supabase from './client';

export async function POST(req: NextRequest) {const formData = await req.formData();

// Remember to enforce type here and after use some lib like zod.js to check itconst files = formData.getAll('files') as File[];

// Thats it, you have your filesconsole.log(files);/* returns [{ name: 'test.jpg', type: 'image/jpg', size: 1024, ...other file props} ]*/

const fileToStorage = files[0];

// supose you have your Supabase client initialized previouslyawait supabase.storage.from(this.bucketName).upload( `/some/path/${fileToStorage.name}`, fileToStorage, { contentType: fileToStorage.type } // Optional);

return NextResponse.json({ message: 'Files Created' });}

And now the Frontend

Actually this part can be as you want it to be, but I will show how I’ve done, using react-hook-form and fetch():

// app/upload/page.tsx

import { useForm, SubmitHandler } from 'react-hook-form';

export default function Upload() { const {register,handleSubmit,formState: { errors },reset, } = useForm();

const onSubmit: SubmitHandler = async (data) => {const formData = new FormData();formData.append('files', data.files);

await fetch('/api/upload', {method: 'POST',body: formData,});

reset(); };

return ();}

Thats all

I know it is very simple, but my first try was using next-connect and multer in Pages dir — Which can be a solution if this one does not fit your need — and that wasn’t really good. So when I arrived in this solution I just ran over here to write and share about it.

Thanks for your attention.

References

Docs | Next.js (nextjs.org)Supabase Javascript ClientGetting started with Vercel Blob | Vercel Docs

相关推荐: